package com.yuandian.customer.perception.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.customer_perception.po.DayReportParams;
import com.yuandian.api.customer_perception.po.OperatorAnalysisParams;
import com.yuandian.api.customer_perception.vo.*;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.customer.perception.mapper.OperatorAnalysisMapper;
import com.yuandian.customer.perception.service.IOperatorAnalysisService;
import com.yuandian.enums.TableNameEnum;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 说明：营业员分析service实现
 * @Author yanjun
 * @Date 2021/3/23 13:53
 */
@Service
public class OperatorAnalysisServiceImpl implements IOperatorAnalysisService {

    @Autowired
    private OperatorAnalysisMapper operatorAnalysisMapper;

    /**
     * 查询营业员排名
     * @param params 营业员分析请求参数
     * @return 通用返回对象
     */
    @Override
    public R queryOperatorRank(OperatorAnalysisParams params) {

        // 2、查询营业员排名列表
        List<OperatorRankVo> orVoList = operatorAnalysisMapper.queryOperatorRank(params);
        if (CollectionUtils.isEmpty(orVoList)) {
            // 无排名数据
            return R.ok(null);
        }
        // 3、判断是否传了工号或姓名，或两个都有传
        int total = orVoList.size(), rank = 1;
        OperatorRankVo result = null;
        String operatorId = params.getOperatorId();
        String operatorName = params.getOperatorName();
        if (StringUtils.isNotEmpty(operatorId) && StringUtils.isNotEmpty(operatorName)) {
            // 3.1、如果两个都有传，找该工号该姓名的营业员的排名情况
            for (int i = 0; i < orVoList.size(); i++) {
                if (operatorId.equals(orVoList.get(i).getOperatorId())
                        && operatorName.equals(orVoList.get(i).getOperatorName())) {
                    result = orVoList.get(i);
                    rank = i + 1;
                    break;
                }
            }
        } else if (StringUtils.isNotEmpty(operatorId)) {
            // 3.2、如果传了工号，找该工号的营业员的排名情况
            for (int i = 0; i < orVoList.size(); i++) {
                if (operatorId.equals(orVoList.get(i).getOperatorId())) {
                    result = orVoList.get(i);
                    rank = i + 1;
                    break;
                }
            }
        } else if (StringUtils.isNotEmpty(operatorName)) {
            // 3.3、如果传了姓名，找该姓名的营业员的排名情况
            for (int i = 0; i < orVoList.size(); i++) {
                if (operatorName.equals(orVoList.get(i).getOperatorName())) {
                    result = orVoList.get(i);
                    rank = i + 1;
                    break;
                }
            }
        } else {
            // 3.4、默认取排名第一的营业员
            result = orVoList.get(0);
        }
        // 4、如果没有符合条件的营业员，返回空
        if (result == null) {
            return R.ok(result);
        }
        // 5、设置排名情况
        result.setRank(rank);
        if (rank == 1) {
            // 排名第1
            result.setRankRate(100.00);
        } else if (rank == total && total > 1) {
            // 排名和总数相等，总数大于1，才是最后一名，这种情况是为了排除总数为1的情况
            result.setRankRate(0.00);
        } else {
            result.setRankRate(new BigDecimal((1 - ((double) rank / total)) * 100)
                    .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        }
        // 6、查询营业员完成业务top5
        params.setOperatorId(result.getOperatorId());
        params.setOperatorName(result.getOperatorName());
        List<OperatorBusiTopVo> obtVoList = operatorAnalysisMapper.queryOperatorBusiTop(params);
        result.setObtVoList(obtVoList);
        return R.ok(result);
    }

    /**
     * 查询营业员各业务情况
     * @param params 营业员分析请求参数
     * @return 通用返回对象
     */
    //@DS("khgzData")
    @Override
    public R queryOperatorBusiSituation(OperatorAnalysisParams params) {

        // 2、查询营业员各业务情况，以受理量降序排序
        List<OperatorRankVo> orVoList = operatorAnalysisMapper.queryOperatorBusiSituation(params);
        if (CollectionUtils.isEmpty(orVoList)) {
            // 无排名数据
            return R.ok(null);
        }
        // 3、计算受理量排名
        int total = orVoList.size(), completeRank = 1;
        OperatorBusiSituationVo result = new OperatorBusiSituationVo();
        OperatorRankVo orVo = null;
        for (int i = 0; i < orVoList.size(); i++) {
            if (orVoList.get(i).getOperatorId().equals(params.getOperatorId())) {
                orVo = orVoList.get(i);
                completeRank = i + 1;
                break;
            }
        }
        if (orVo != null) {
            result.setCompleteCount(orVo.getCompleteCount());
            result.setCompleteRank(completeRank);
            if (completeRank == 1) {
                // 排名第1
                result.setCompleteRankRate(100.00);
            } else if (completeRank == total && total > 1) {
                // 排名和总数相等，总数大于1，才是最后一名，这种情况是为了排除总数为1的情况
                result.setCompleteRankRate(0.00);
            } else {
                result.setCompleteRankRate(new BigDecimal((1 - ((double) completeRank / total)) * 100)
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            }
        }
        // 4、计算平均用时排名，先按平均用时降序排序
        List<OperatorRankVo> sortedList = orVoList
                .stream()
                .sorted(Comparator.comparing(OperatorRankVo::getAvgVisitTime, Comparator.nullsFirst(Double::compareTo)).reversed())
                .collect(Collectors.toList());
        int avgVisitTimeRank = 1;
        orVo = null;
        for (int i = 0; i < sortedList.size(); i++) {
            if (sortedList.get(i).getOperatorId().equals(params.getOperatorId())) {
                orVo = sortedList.get(i);
                avgVisitTimeRank = i + 1;
                break;
            }
        }
        if (orVo != null) {
            result.setAvgVisitTime(orVo.getAvgVisitTime());
            result.setAvgVisitTimeRank(avgVisitTimeRank);
            if (avgVisitTimeRank == 1) {
                // 排名第1
                result.setAvgVisitTimeRankRate(100.00);
            } else if (avgVisitTimeRank == total && total > 1) {
                // 排名和总数相等，总数大于1，才是最后一名，这种情况是为了排除总数为1的情况
                result.setAvgVisitTimeRankRate(0.00);
            } else {
                result.setAvgVisitTimeRankRate(new BigDecimal((1 - ((double) avgVisitTimeRank / total)) * 100)
                        .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            }
        }
        return R.ok(result);
    }

    /**
     * 查询营业员统计列表
     * @param params 营业员分析请求参数
     * @return 通用返回对象
     */
    //@DS("khgzData")
    @Override
    public R queryOperatorStatisticsList(OperatorAnalysisParams params) {
        // 设置表名
//        ShardResult shardResult = tableShardingService.getBpmTableList("busi_detail_operator_stat_m", params);
//        if (shardResult.getCode() != ApiResultCode.SUCCESS.getCode()) {
//            return R.setFail(shardResult.getMessage());
//        }
        // 设置分页参数
        Page<OperatorStatisticsVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        // 执行查询
        List<OperatorStatisticsVo> list = operatorAnalysisMapper.queryOperatorStatisticsList(params, page);
        return R.ok(new PageDataInfo(page, list));
    }

    /**
     * 查询营业员排序列表
     * @param params 营业员分析请求参数
     * @return 通用返回对象
     */
    //@DS("khgzData")
    @Override
    public R queryOperatorRankList(OperatorAnalysisParams params) {
        // 设置表名
//        ShardResult shardResult = tableShardingService.getBpmTableList("busi_detail_operator_stat_m", params);
//        if (shardResult.getCode() != ApiResultCode.SUCCESS.getCode()) {
//            return R.setFail(shardResult.getMessage());
//        }
        // 设置分页参数
        Page<OperatorRankListVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        // 执行查询
        List<OperatorRankListVo> list = operatorAnalysisMapper.queryOperatorRankList(params, null);
        int total = list.size();
        List<OperatorRankListVo> sortedList = list;
        // 如果不是按受理量降序，则对数据重新排序
        if (!("completeCount".equals(params.getOrderByColumn()) && "desc".equals(params.getIsAsc()))) {
            sortedList = list
                    .stream()
                    .sorted(Comparator.comparing(OperatorRankListVo::getCompleteCount).reversed())
                    .collect(Collectors.toList());
        }
        // 排序后的数据设置排名
        for (int i = 0; i < sortedList.size(); i++) {
            sortedList.get(i).setRank(i + 1);
        }
        // 获取工号和排名的映射
        Map<String, Integer> collect = sortedList
                .stream()
                .collect(Collectors.toMap(OperatorRankListVo::getOperatorId, OperatorRankListVo::getRank, (k1, k2) -> k1));
        // 获取分页视图
        double maxPage = Math.ceil(new BigDecimal((double) total / params.getPageSize())
                .setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        if (params.getPageNum() > maxPage) {
            params.setPageNum(new Double(maxPage).longValue());
        }
        int fromIndex = Long.valueOf((params.getPageNum() - 1) * params.getPageSize()).intValue();
        int toIndex = Long.valueOf(params.getPageNum() * params.getPageSize()).intValue();
        if (toIndex > total) {
            toIndex = total;
        }
        List<OperatorRankListVo> view = list.subList(fromIndex, toIndex);
        // 设置排名
        for (int j = 0; j < view.size(); j++) {
            OperatorRankListVo vo = list.get(j);
            vo.setRank(collect.get(vo.getOperatorId()));
        }
        return R.ok(new PageDataInfo(total, view));
    }

    /**
     * 查询运维日报操作员统计topN
     * @param params 运维日报请求参数
     * @return 通用返回对象
     */
    //@DS("khgzData")
    @Override
    public R queryReportOperatorStatisticsTopN(DayReportParams params) {
        // 1、设置表名
        params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
        // 2、设置默认排序
        if (StringUtils.isEmpty(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        // 3、设置排序字段
        switch (params.getOperatorType()) {
            case COMPLETE_COUNT:
                params.setOrderByColumn("completeCount");
                break;
            case AVG_VISIT_TIME:
                params.setOrderByColumn("avgVisitTime");
                break;
            case FAIL_COUNT:
                params.setOrderByColumn("failCount");
                break;
            case FAIL_RATE:
                params.setOrderByColumn("failRate");
                break;
        }
        // 4、执行查询
        List<ReportOperatorStatisticsTopVo> list = operatorAnalysisMapper.queryReportOperatorStatisticsTopN(params);
        return R.ok(list);
    }

    /**
     * 查询运维日报操作员统计量比例
     * @param params 运维日报请求参数
     * @return 通用返回对象
     */
    //@DS("khgzData")
    @Override
    public R queryReportOperatorProportion(DayReportParams params) {
        // 1、设置表名
        params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
        // 2、设置默认排序
        if (StringUtils.isEmpty(params.getIsAsc())) {
            params.setIsAsc("desc");
        }
        // 3、设置排序字段
        switch (params.getOperatorType()) {
            case COMPLETE_COUNT:
                params.setOrderByColumn("completeCount");
                break;
            case AVG_VISIT_TIME:
                params.setOrderByColumn("avgVisitTime");
                break;
            case FAIL_COUNT:
                params.setOrderByColumn("failCount");
                break;
            case FAIL_RATE:
                params.setOrderByColumn("failRate");
                break;
        }
        // 4、执行查询
        List<ReportOperatorProportionVo> list = operatorAnalysisMapper.queryReportOperatorProportion(params);
        return R.ok(list);
    }
}
